package com.example.knowledgeget1.FileOperate;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class FileChatService {

    private final String API_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1/files";
    private final String CHAT_API_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions";

    @Value("${w.apikey}")
    private String authorizationHeader;

    public List<Map<String, String>> uploadFile(MultipartFile file) throws IOException {
        File tempFile = File.createTempFile("upload", ".tmp");
        tempFile.deleteOnExit();
        file.transferTo(tempFile);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(API_URL);

        httpPost.setHeader("Authorization", authorizationHeader);

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();

        FileBody fileBody = new FileBody(tempFile);
        builder.addPart("file", fileBody);

        builder.addPart("purpose", new StringBody("file-extract", ContentType.TEXT_PLAIN));

        HttpEntity entity = builder.build();
        httpPost.setEntity(entity);

        CloseableHttpResponse response = httpClient.execute(httpPost);
        try {
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                String responseString = EntityUtils.toString(responseEntity);
                JSONObject jsonObject = new JSONObject(responseString);
                String fileId = jsonObject.getString("id");
                List<Map<String, String>> jsonData = fileChat(httpClient, fileId);
                deleteFileById(httpClient, fileId);
                return jsonData;
            }
        } finally {
            response.close();
        }
        return null;
    }

    private List<Map<String, String>> fileChat(CloseableHttpClient httpClient, String fileId) {
        HttpPost httpPost = new HttpPost(CHAT_API_URL);
        httpPost.setHeader("Authorization", authorizationHeader);
        httpPost.setHeader("Content-Type", "application/json");

        String jsonPayload = "{\"model\": \"qwen-long\",\"messages\": [{\"role\": \"system\",\"content\": \"你是一个文本解读专家。\"},{\"role\": \"system\",\"content\": \"fileid://" + fileId + "\"},{\"role\": \"user\",\"content\": \"请仔细阅读文件，判断出这个文件的主要领域，提取出文件中提及的与该领域相关的所有概念和知识点的名称，直接用如下json格式封装他们，json格式中是一个列表，每一个列表项包括一个id（id用来标识每一个列表项，从0开始）和一个提取到的name，不需要额外的解释或者描述。\"}]}";
        String jsonPayload1 = "{\"model\": \"qwen-long\",\"messages\": [{\"role\": \"system\",\"content\": \"你是一个文本解读专家。\"},{\"role\": \"system\",\"content\": \"fileid://" + fileId + "\"},{\"role\": \"user\",\"content\": \"请仔细阅读文件，判断出这个文件的主要领域，以目录的方式输出该文件的内容，且每个目录下有分目录，同时给出目录和分目录的标题内容以及分目录下讲述的知识点，不需要额外的解释或者描述。\"}]}";
        httpPost.setEntity(new StringEntity(jsonPayload1, ContentType.APPLICATION_JSON));

        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
            HttpEntity responseEntity = response.getEntity();
            System.out.println(response);
            if (responseEntity != null) {
                String responseString = EntityUtils.toString(responseEntity);
                List<Map<String, String>> jsonData = extractJsonDataFromResponse(responseString);
                return jsonData;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private List<Map<String, String>> extractJsonDataFromResponse(String responseString) {
        List<Map<String, String>> resultList = new ArrayList<>();
        try {
            JSONObject jsonResponse = new JSONObject(responseString);
            JSONArray choices = jsonResponse.getJSONArray("choices");
            if (choices.length() > 0) {
                JSONObject choice = choices.getJSONObject(0);
                JSONObject message = choice.getJSONObject("message");
                String content = message.getString("content");
                int start = content.indexOf('[');
                int end = content.lastIndexOf(']');
                if (start == -1 || end == -1 || end < start) {
                    throw new IllegalArgumentException("Invalid JSON data in the string.");
                }
                content = content.substring(start, end+1);
                JSONArray jsonArray = new JSONArray(content);
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject item = jsonArray.getJSONObject(i);
                    Map<String, String> map = Map.of("id", String.valueOf(item.getInt("id")), "name", item.getString("name"));
                    resultList.add(map);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultList;
    }

    private void deleteFileById(CloseableHttpClient httpClient, String fileId) {
        String deleteUrl = API_URL + "/" + fileId;

        HttpDelete deleteRequest = new HttpDelete(deleteUrl);
        deleteRequest.setHeader("Authorization", "Bearer " + authorizationHeader);

        CloseableHttpResponse deleteResponse = null; // Initialize outside the try block

        try {
            deleteResponse = httpClient.execute(deleteRequest);
            int statusCode = deleteResponse.getStatusLine().getStatusCode();

            while (statusCode == 308) {
                String locationHeader = deleteResponse.getFirstHeader("Location").getValue();
                deleteUrl = locationHeader;

                deleteRequest = new HttpDelete(deleteUrl);
                deleteRequest.setHeader("Authorization", "Bearer " + authorizationHeader);

                deleteResponse = httpClient.execute(deleteRequest); // Reassign deleteResponse here
                statusCode = deleteResponse.getStatusLine().getStatusCode();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (deleteResponse != null) {
                    deleteResponse.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //将选中的内容发给大模型解析
    public List<List<Map<String, String>>> queryModelWithContent(List<String> contents) {
        List<List<Map<String, String>>> results = new ArrayList<>();
        CloseableHttpClient httpClient = HttpClients.createDefault();

        for (String content : contents) {
            String prompt = content ;
            String jsonResponse = sendRequestToModel(httpClient, prompt);
            if (jsonResponse != null) {
                List<Map<String, String>> extractedData = extractJsonDataFromResponse(jsonResponse);
                results.add(extractedData);
            }
        }

        return results;
    }

    private String sendRequestToModel(CloseableHttpClient httpClient, String prompt) {
        try {
            HttpPost httpPost = new HttpPost(CHAT_API_URL);
            httpPost.setHeader("Authorization", authorizationHeader);
            httpPost.setHeader("Content-Type", "application/json");

            String jsonPayload = new JSONObject()
                    .put("model", "qwen-long")
                    .put("messages", new JSONArray()
                            .put(new JSONObject().put("role", "system").put("content", "你是一个文本解析专家。下面有一段文本:"))
                            .put(new JSONObject().put("role", "system").put("content", prompt))
                            .put(new JSONObject().put("role", "user").put("content", "请仔细阅读文本中的内容，判断出这段文本的主要领域，提取出文本中提及的与该领域相关的所有概念和知识点的内容(用一句话概括知识点，而不是一个名词,并且用原来的语言来概括，即原文是英文就是英文，原文是中文就是中文)，直接用如下json格式封装他们，json格式中是一个列表，每一个列表项包括一个id（id用来标识每一个列表项，从0开始）和一个提取到的name，类似```json\\n[\\n  {\\\"id\\\": 0, \\\"name\\\": \\\"赋值运算符......\\\"},\\n  {\\\"id\\\": 1, \\\"name\\\": \\\"词法语法......\\\"}\\n]\\n```不需要额外的解释或者描述。请按要求解析以下内容：\n\n")))
                    .toString();
            httpPost.setEntity(new StringEntity(jsonPayload, ContentType.APPLICATION_JSON));
            System.out.println(jsonPayload);
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                if (response.getEntity() != null) {
                    String responseBody = EntityUtils.toString(response.getEntity());
                    System.out.println(responseBody);
                    return responseBody;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
